+2008-03-28 Richard Hult <richard@imendio.com>
+
+ * gdk/quartz/gdkevents-quartz.c: (gdk_event_translate),
+ (_gdk_quartz_events_trigger_crossing_events): Defer the generated
+ event to the mainloop and don't generate one at all if the
+ toplevel didn't change. Use the actual window and not the toplevel
+ as event window. These changes make the generated crossing events
+ match the X11 behavior and fixes issues with e.g. tooltips,
+ comboboxes and menus.
+
+ * gdk/quartz/GdkQuartzView.c: Don't update the tracking rect if
+ the view has no window, it will be updated as soon as it's put
+ inside a window.
+
+ * gdk/quartz/gdkwindow-quartz.c:
+ (_gdk_quartz_window_debug_highlight): Make it possible to track
+ multiple windows with debug highlighting.
+ (show_window_internal): Remove workaround for tooltips and popups
+ that is no longer needed with the above changes.
+
2008-03-26 Federico Mena Quintero <federico@novell.com>
* gtk/gtkfilechooserentry.c (commit_completion_and_refresh): New
-(void)setFrame:(NSRect)frame
{
[super setFrame:frame];
- [self updateTrackingRect];
+
+ if ([self window])
+ [self updateTrackingRect];
}
@end
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
- _gdk_quartz_window_debug_highlight (window);
+ _gdk_quartz_window_debug_highlight (window, 0);
#endif /* G_ENABLE_DEBUG */
if (window)
* window.
*/
void
-_gdk_quartz_events_trigger_crossing_events (void)
+_gdk_quartz_events_trigger_crossing_events (gboolean defer_to_mainloop)
{
NSPoint point;
- gint x;
- gint y;
+ gint x, y;
+ gint x_toplevel, y_toplevel;
GdkWindow *mouse_window;
+ GdkWindow *toplevel;
GdkWindowImplQuartz *impl;
guint flags = 0;
NSTimeInterval timestamp = 0;
NSEvent *current_event;
NSEvent *nsevent;
+ if (defer_to_mainloop)
+ {
+ nsevent = [NSEvent otherEventWithType:NSApplicationDefined
+ location:NSZeroPoint
+ modifierFlags:0
+ timestamp:0
+ windowNumber:0
+ context:nil
+ subtype:GDK_QUARTZ_EVENT_SUBTYPE_FAKE_CROSSING
+ data1:0
+ data2:0];
+ [NSApp postEvent:nsevent atStart:NO];
+ return;
+ }
+
point = [NSEvent mouseLocation];
x = point.x;
y = _gdk_quartz_window_get_inverted_screen_y (point.y);
if (!mouse_window || mouse_window == _gdk_root)
return;
- /* NSMouseEntered always happens on the toplevel. */
- mouse_window = gdk_window_get_toplevel (mouse_window);
+ toplevel = gdk_window_get_toplevel (mouse_window);
+
+ /* We ignore crossing within the same toplevel since that is already
+ * handled elsewhere.
+ */
+ if (toplevel == gdk_window_get_toplevel (current_mouse_window))
+ return;
+
+ get_converted_window_coordinates (_gdk_root,
+ x, y,
+ toplevel,
+ &x_toplevel, &y_toplevel);
get_converted_window_coordinates (_gdk_root,
x, y,
mouse_window,
&x, &y);
- impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (mouse_window)->impl);
-
/* Fix up the event to be less fake if possible. */
current_event = [NSApp currentEvent];
if (current_event)
timestamp = [current_event timestamp];
}
+ if (timestamp == 0)
+ timestamp = GetCurrentEventTime ();
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
nsevent = [NSEvent otherEventWithType:NSApplicationDefined
- location:NSMakePoint(x, impl->height - y)
+ location:NSMakePoint (x_toplevel, impl->height - y_toplevel)
modifierFlags:flags
timestamp:timestamp
windowNumber:[impl->toplevel windowNumber]
data2:0];
#ifdef G_ENABLE_DEBUG
- /*_gdk_quartz_window_debug_highlight (mouse_window);*/
+ /*_gdk_quartz_window_debug_highlight (mouse_window, 0);*/
#endif
synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, x, y);
}
}
+ /* Handle our generated "fake" crossing events. */
+ if ([nsevent type] == NSApplicationDefined &&
+ [nsevent subtype] == GDK_QUARTZ_EVENT_SUBTYPE_FAKE_CROSSING)
+ {
+ _gdk_quartz_events_trigger_crossing_events (FALSE);
+ return TRUE;
+ }
+
/* Keep track of button state, since we don't get that information
* for key events.
*/
void _gdk_quartz_window_detach_from_parent (GdkWindow *window);
void _gdk_quartz_window_did_become_main (GdkWindow *window);
void _gdk_quartz_window_did_resign_main (GdkWindow *window);
-void _gdk_quartz_window_debug_highlight (GdkWindow *window);
+void _gdk_quartz_window_debug_highlight (GdkWindow *window,
+ gint number);
/* Events */
typedef enum {
void _gdk_quartz_events_update_cursor (GdkWindow *window);
void _gdk_quartz_events_send_map_events (GdkWindow *window);
GdkEventMask _gdk_quartz_events_get_current_event_mask (void);
-void _gdk_quartz_events_trigger_crossing_events(void);
+void _gdk_quartz_events_trigger_crossing_events(gboolean defer_to_mainloop);
extern GdkWindow *_gdk_quartz_keyboard_grab_window;
extern GdkWindow *_gdk_quartz_pointer_grab_window;
}
void
-_gdk_quartz_window_debug_highlight (GdkWindow *window)
+_gdk_quartz_window_debug_highlight (GdkWindow *window, gint number)
{
GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
gint x, y;
GdkWindow *toplevel;
gint tx, ty;
- static NSWindow *debug_window;
- static NSRect old_rect;
+ static NSWindow *debug_window[10];
+ static NSRect old_rect[10];
NSRect rect;
+ NSColor *color;
+
+ g_return_if_fail (number >= 0 && number <= 9);
if (window == _gdk_root)
return;
if (window == NULL)
- return;
+ {
+ if (debug_window[number])
+ [debug_window[number] close];
+ debug_window[number] = NULL;
+
+ return;
+ }
toplevel = gdk_window_get_toplevel (window);
get_ancestor_coordinates_from_child (window, 0, 0, toplevel, &x, &y);
x += tx;
y += ty;
- rect = NSMakeRect (x,
- _gdk_quartz_window_get_inverted_screen_y (y + impl->height),
- impl->width, impl->height);
+ rect = NSMakeRect (x,
+ _gdk_quartz_window_get_inverted_screen_y (y + impl->height),
+ impl->width, impl->height);
- if (debug_window &&
- rect.origin.x == old_rect.origin.x &&
- rect.origin.y == old_rect.origin.y &&
- rect.size.width == old_rect.size.width &&
- rect.size.height == old_rect.size.height)
- {
- return;
- }
+ if (debug_window[number] && NSEqualRects (rect, old_rect[number]))
+ return;
+
+ old_rect[number] = rect;
- old_rect = rect;
+ if (debug_window[number])
+ [debug_window[number] close];
- if (debug_window)
- [debug_window close];
+ debug_window[number] = [[NSWindow alloc] initWithContentRect:rect
+ styleMask:NSBorderlessWindowMask
+ backing:NSBackingStoreBuffered
+ defer:NO];
- debug_window = [[NSWindow alloc] initWithContentRect:rect
- styleMask:NSBorderlessWindowMask
- backing:NSBackingStoreBuffered
- defer:NO];
+ switch (number)
+ {
+ case 0:
+ color = [NSColor redColor];
+ break;
+ case 1:
+ color = [NSColor blueColor];
+ break;
+ case 2:
+ color = [NSColor greenColor];
+ break;
+ case 3:
+ color = [NSColor yellowColor];
+ break;
+ case 4:
+ color = [NSColor brownColor];
+ break;
+ case 5:
+ color = [NSColor purpleColor];
+ break;
+ default:
+ color = [NSColor blackColor];
+ break;
+ }
- [debug_window setBackgroundColor:[NSColor redColor]];
- [debug_window setAlphaValue:0.4];
- [debug_window setOpaque:NO];
- [debug_window setReleasedWhenClosed:YES];
- [debug_window setIgnoresMouseEvents:YES];
- [debug_window setLevel:NSFloatingWindowLevel];
+ [debug_window[number] setBackgroundColor:color];
+ [debug_window[number] setAlphaValue:0.4];
+ [debug_window[number] setOpaque:NO];
+ [debug_window[number] setReleasedWhenClosed:YES];
+ [debug_window[number] setIgnoresMouseEvents:YES];
+ [debug_window[number] setLevel:NSFloatingWindowLevel];
- [debug_window orderFront:nil];
+ [debug_window[number] orderFront:nil];
}
gboolean
if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
_gdk_quartz_window_attach_to_parent (window);
- /* Create a crossing event for managed windows that pop up under the
- * mouse. Part of the workarounds for problems with the tracking rect API.
+ /* Create a crossing event for windows that pop up under the mouse. Part
+ * of the workarounds for problems with the tracking rect API.
*/
- if (impl->toplevel && private->window_type != GDK_WINDOW_TEMP)
- _gdk_quartz_events_trigger_crossing_events ();
+ if (impl->toplevel)
+ _gdk_quartz_events_trigger_crossing_events (TRUE);
GDK_QUARTZ_RELEASE_POOL;
}